On this page

Skip to content

A Brief Discussion on Environment Name Configuration and Application in ASP.NET Core

This article was prompted by a colleague's unfamiliarity with ASP.NET Core deployment, as well as some details I had previously misunderstood, so I decided to write this post to organize the relevant information.

Configuration Settings

In the legacy .NET Framework, configuration settings were primarily used to switch between different configuration files. For details, please refer to "In .NET Framework, regarding the application of Web.config (App.config)". Using Web.config as the main file, you could override its content via Web.{Configuration}.config. In each configuration, you could define corresponding constants and use conditional compilation to switch between them.

Environment Names

In .NET Core and .NET 5 and later versions, in addition to configuration settings, the environment variable EnvironmentName was added to distinguish between different environments. EnvironmentName can be any value, but ASP.NET Core provides the following default values:

  • Development: Used for local development.
  • Staging: Used for pre-release versions.
  • Production: The default value if DOTNET_ENVIRONMENT and ASPNETCORE_ENVIRONMENT are not set; generally used for the production environment.

These three environment names can correspond to the master, pre-production, and production branches of GitLab Flow. If GitLab Flow defines other environment branches, you can also set the corresponding environment names.

In ASP.NET Core, appsettings.json is primarily used as the configuration file, and appsettings.{Environment}.json is used to override the content of the main configuration file. The difference from the legacy Web.config is that Web.config used the Web.{Configuration}.config Transform mechanism to replace content, generating a new Web.config after build; whereas appsettings.json follows the loading order, where settings loaded later override previous ones.

When ASP.NET Core executes WebApplication.CreateBuilder(args), it internally calls the extension method HostingHostBuilderExtensions.ConfigureDefaults(), which loads appsettings.json and appsettings.{Environment}.json. The following is an excerpt of the code:

csharp
builder.ConfigureAppConfiguration((hostingContext, config) => {
    IHostEnvironment env = hostingContext.HostingEnvironment;
    bool reloadOnChange = GetReloadConfigOnChangeValue(hostingContext);

    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange);

    if (env.IsDevelopment() && env.ApplicationName is { Length: > 0 }) {
        var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
        if (appAssembly is not null) {
            config.AddUserSecrets(appAssembly, optional: true, reloadOnChange: reloadOnChange);
        }
    }

    config.AddEnvironmentVariables();

    if (args is { Length: > 0 }) {
        config.AddCommandLine(args);
    }
})

WARNING

Since ASP.NET Core internally loads appsettings.json and appsettings.{Environment}.json, manually loading appsettings.json again might override the settings in appsettings.{Environment}.json. I once failed to read appsettings.{Environment}.json for unknown reasons and, misled by the Web.config mindset, added these two lines in Program for testing. I then tried commenting out the reference to appsettings.{Environment}.json and kept wondering why the settings weren't being applied. It wasn't until I saw a colleague comment out both lines for testing that I realized where the problem was.

Methods for Setting Environment Variables

Local Development

ASP.NET Core allows you to set the local development environment in the Properties\launchSettings.json file. The environment value set here will appear in the Visual Studio simulator list and will override global environment settings. The following is a default example; for more specific settings, please refer to the MSDN article "Development and launchSettings.json".

json
{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:59481",
      "sslPort": 44308
    }
  },
  "profiles": {
    "Sample": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:7152;http://localhost:5105",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Using Visual Studio Publishing

For publishing methods, please refer to Web Project Publishing from my previous article. Although it was written for the ASP.NET version, the operation for ASP.NET Core is the same. The only difference is that you need to add the following content to the XML to set the environment name:

xml
<EnvironmentName>Staging</EnvironmentName>

After publishing, the following content will be added to Web.config, and IIS will use this content as the value for the environment variable:

xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\KunYou.KyFido.Backend.WebApi.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
        <!--Extra generated content settings-->
        <environmentVariables>
          <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
        </environmentVariables>
      </aspNetCore>
    </system.webServer>
  </location>
</configuration>

TIP

In the past, when setting Publish.xml in ASP.NET, you could set <ExcludeFilesFromDeployment> or <ExcludeFoldersFromDeployment> to exclude specific files or folders. However, this setting is ineffective in ASP.NET Core, so you cannot use this method to exclude redundant appsettings.{Environment}.json files.

Using Dockerfile Configuration

dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
# Add this line to set the environment variable
ENV ASPNETCORE_ENVIRONMENT=Staging

Operating Environment Settings

ASP.NET Core uses the IWebHostEnvironment object to define environment-related operations. The IHostEnvironment implemented by this interface defines the EnvironmentName property. In addition, the extension methods IsDevelopment(), IsStaging(), and IsProduction() are defined in HostEnvironmentEnvExtensions to determine the current environment name at runtime. For custom environment names, you can use IsEnvironment({environmentName}) to determine them.

Change Log

  • 2024-07-12 Initial version created.